/*
 * =====================================================================================
 *
 *       Filename:  cl_tcp_client.hxx
 *
 *    Description:  
 *
 *        Version:  1.0
 *        Created:  04/28/2011 01:36:37 PM
 *       Revision:  none
 *       Compiler:  gcc
 *
 *         Author:  Chen Ken (Ken), zlchen.ken@gmail.com
 *        Company:  EMC
 *
 * =====================================================================================
 */

#ifndef _CL_TCP_CLIENT_HXX_
#define _CL_TCP_CLIENT_HXX_

#include <atomic>
#include <memory>
#include <functional>
#include <string>
#include "cl_net_callback.hxx"
#include "cl_socket_addr.hxx"
#include "cl_tcp_conn.hxx"

namespace neo
{
class CLEventLooper;
class CLChannel;
class CLClientSocket;

class CLTcpClient
{
public:
  CLTcpClient(const std::string& server, int port);
	~CLTcpClient();
  void connect(void);
  void disconnect(void);
	void enableRetry(void);
  void setConnCallback(const CLConnCallback& cb);
	void setMessageCallback(const CLMessageCallback& cb);
	void setWriteCompleteCallback(const CLWriteCompleteCallback& cb);

private:
  void handleNewConnection(int connfd, CLSocketAddrUPtr serverAddr);
	void handleFailConnection(void);
	void removeConnection(const CLTcpConnSPtr& conn);
	void setState(int state);

private:
  enum State
	{
    TCP_CONN_CONNECTING,
    TCP_CONN_DISCONNECTED,
    TCP_CONN_CONNECTED 
	};

private:
	std::unique_ptr<CLEventLooper> m_ioLooper;
	std::unique_ptr<CLChannel> m_ioChannel;
  std::unique_ptr<CLClientSocket> m_connector;
  CLConnCallback m_connCallback;
  CLMessageCallback m_msgCallback;
	CLWriteCompleteCallback m_writeCompleteCallback;
	CLTcpConnSPtr m_connection;
  std::atomic<bool> m_retry;
	std::atomic<int> m_state;
	int m_nextConnId;
};

} // neo

#endif //_CL_TCP_CLIENT_HXX_

